package nz.ac.massey.cs.sdc.log4jassignment.s09007369;

import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;

public class MemoryAppender extends AppenderSkeleton implements MemoryAppenderMBean{

	private int maxSize = 5000000;
	private List<LoggingEvent> primaryList, secondaryList, resultList;
	
	public MemoryAppender() {
		primaryList = new LinkedList<LoggingEvent>();
		secondaryList = new LinkedList<LoggingEvent>();
	}
	
	public MemoryAppender(List<LoggingEvent> list) {
		this.primaryList = (LinkedList<LoggingEvent>) list;
		secondaryList = new LinkedList<LoggingEvent>();
	}
	
	public List<LoggingEvent> getLogs()
	{
		if(resultList != null) 
			resultList.clear();
		else
			resultList = new LinkedList<LoggingEvent>();
		//from oldest
		for(LoggingEvent e : secondaryList)
			resultList.add(e);
		//to newest	
		for(LoggingEvent e : primaryList)
			resultList.add(e);
			
		return resultList;		
	}


	@Override
	public void close() {		
	}

	@Override
	public boolean requiresLayout() {
		// we mast use StringTemplateLayout, so true
		return true;
	}

	@Override
	protected void append(LoggingEvent arg0) {
		
		if(primaryList.size()+1 >= maxSize){			
			secondaryList.add(primaryList.remove(0));			
		}	
		
		primaryList.add(arg0);
	}

	// MBean
	@Override
	public LoggingEvent[] getPrimaryList() {
		LoggingEvent[] rez = new LoggingEvent[primaryList.size()];
		return rez = primaryList.toArray(rez);
	}

	/**
	 * Method from MBean
	 */
	@Override
	public LoggingEvent[] getSecondaryList() {
		LoggingEvent[] rez = new LoggingEvent[secondaryList.size()];
		return rez = secondaryList.toArray(rez);
	}

	/**
	 * Method from MBean
	 */
	@Override
	public long getNumberOfLogs() {
		
		return primaryList.size()+secondaryList.size();
	}

	/**
	 * Method from MBean
	 */
	@Override
	public long getCachedLogs() {
		
		long rez = 0;
		for(LoggingEvent e : primaryList) rez += getLayout().format(e).toCharArray().length;
		for(LoggingEvent e : secondaryList) rez += getLayout().format(e).toCharArray().length;
		return rez;
		
	}

}
